#ifndef __MY_OZI_INTERNALS
#define __MY_OZI_INTERNALS

#include <gfl/gfl_all.h>
#include <HGrid.h>

#include "HWindow.h"
#include "HCFGStorage.h"
#include "oziapi.h"

#include "Data.h"

//---------------------------------------------------------------------------
//  ControlOverride
//---------------------------------------------------------------------------
class ControlAccess : public TControl {
  public:
    __property Font;
    __property Color;
    __property Width;
    __property Height;
};

LOCALSTRUCT( ControlOverride )
  TControl *Ctl;
  bool      Font0Used;
  TFont    *Font0;
  bool      Font1Used;
  TFont    *Font1;
  bool      Color0Used;
  TColor    Color0;
  bool      Color1Used;
  TColor    Color1;

  __fastcall ControlOverride( void );
  __fastcall ~ControlOverride();
};

LOCALCLASSBASE( OverrideArray, public MyArray<PControlOverride> )
  private:
    TControl *PopupControl;
    void __fastcall idFont(TObject *Sender);
    void __fastcall idColor(TObject *Sender);

  public:
    __fastcall OverrideArray( void );

    PControlOverride __fastcall Find( TControl *ctl );
    PControlOverride __fastcall AddFind( TControl *ctl );

    void __fastcall OverrideFont( TControl *ctl, int num );
    void __fastcall OverrideColor( TControl *ctl, int num );
    void __fastcall Notify( TControl *ctl );

    void __fastcall PrepareOverridePopup( TMenuItem *mi );
    void __fastcall PrepareOverridePopup( TMenuItem *mi, TControl *ctl );

    void __fastcall Save( PHConfigItem cfg );
    void __fastcall Load( TWinControl *Base, PHConfigItem cfg );

    TNotifyEvent OnControlChange;
};

//---------------------------------------------------------------------------
//  HCoord
//---------------------------------------------------------------------------
LOCALSTRUCT( HCoord )
  double Lat,   //N
         Lon;   //E
  int    x, y;
  time_t Measure;

  HCoord( void ) { Lat = Lon = 0; x = y = 0; Measure = 0; }
  HCoord( double lat, double lon, int _x, int _y ) { Set( lat,lon,_x,_y ); }

  void Set( double lat, double lon, int _x, int _y ) { Lat = lat; Lon = lon; x = _x; y = _y; }
  int  Size( const HCoord& p );
  int  QSize( const HCoord& p );

  bool Diff( int _x, int _y, int avg ) { return Abs(x-_x) > avg || Abs(y-_y) > avg; }
};

#define COORDLINE_ID  MK_ID( 'L','n','i',1 )

LOCALCLASSBASE( HCoordLine, public MyRefArray<HCoord> )
  public:
    HCoordLine( void );

    void    AddPoint( double lat, double lon, int x, int y, int avg );
    int     Size( void );
    int     DirectSize( void );
    PHCoord LastPoint( void );

    HCoord Start;

    bool Save( HOStream& s );
    bool Load( HIStream& s );
};

#define COORDPATH_ID  MK_ID( 'P','t','i',1 )
#define COORPLACE_ID  MK_ID( 'P','l','s',1 )

LOCALCLASSBASE( HCoordPath, public MyArray<PHCoordLine> )
  public:
    HCoordPath( void );

    bool Save( HOStream& s );
    bool Load( HIStream& s );

    HCoordLine Places;
};

//[oz_Main.cpp]
typedef void __fastcall (__closure *TOziEvent)( double Lat,double Lon,double Speed,double Head,double Mag,double Alt,int x,int y );

void OziInit( void );
void OziClose( void );
BOOL OziInited( void );

void OziRegisterEvent( TOziEvent ev );
void OziUnregisterEvent( TOziEvent ev );

enum octConnectType {
  octOzi,
  octFile,
  octPort,
  octNone
};

bool OziConnected( void );
void OziDisconnect( void );
void OziConnect( void );
void OziConnectProcess( void );

void CALLBACK idOZIPos(double Lat,double Lon,double Speed,double Head,double Mag,double Alt );

extern HWND MainWindow;

//[oz_Cfg.cpp]
bool Configure( TForm *Owner );

//[ozf_TrackCfg.cpp]
STRUCT( TrackOptions )
  HCaptionButton_t CState;            // Controls window state
  int              CHeight;           // Controls window height
  HCaptionButton_t PState;            // Points window state
  int              PHeight;           // Points window height
  HCaptionButton_t PlState;           // Places window state
  int              PlHeight;          // Places window height
  bool             Autosave;          // GOPT( "Track/Autosave",     true );
  bool             LoadAutosave;      // Load saved track at next run
  PathString       AutosaveFile;      // GOPT( "Track/AutosaveFile", "autosave.path" );
  int              AutosavePer;       // Number of min between autosave track data
  bool             CompressData;      // GOPT( "CompressData", false )
  int              Scale;             // GOPT( "Track/Scale", 100 )
  int              ResizeSize;        // Wnd border height
  int              PathPointWidth;    // Point size
  int              PathLineWidth;     // Track line width
  TColor           PathSelLineColor;  // Selected track line
  TColor           PathLineColor;     // track line color
  bool             DrawPathPoints;    // Draw track points
  TColor           NearestPointColor; // Color of neares point
  TColor           PathDirectColor;   // Direct line track color
  int              PathDirectWidth;   // Direcl line width
  TColor           PathCurrentColor;  // Current point color
  TColor           PathPointColor;    // Inactive track point color
  TColor           PathSelDirectColor;// Selected direct color
  TColor           InfoColor;         // Info bar color
  bool             DrawStartTime;     // Draw start time
  bool             DrawNumber;        // Draw point number
  bool             DrawDist;          // Draw distance info
  bool             DrawEtaTime;       // Draw info time from prev point
  bool             DrawAvgSpeed;      // Draw info: average speed
  TColor           BkColor;           // Track bk color
  TColor           GridColor;         // Meter grid color
  bool             DrawInfo;          // Draw nfo for every point
  int              InfoFont;          // Info bar font size
  TColor           InfoFontColor;     // Info font color
  int              PlaceSize;         // Place draw size
  int              PlaceCenterSize;   // Place center size
  TColor           PlaceColor;        // Place color
  TColor           PlaceHandleColor;  // Place handle color
  bool             DrawPlaceNum;      // Draw place number
  TColor           PlaceNumColor;     // Place bk color
  TColor           PlaceNumFontColor; // Place font color
  int              PlaceNumFontSize;  // Place font size
  int              CurLength;         // Current point arrow size
  TColor           CurLineColor;      // Current position line color
  int              CurLineWidth;      // Current pos line width
  int              CurArrowSize;      // Current pos arrow head size
  int              CurPointWidth;     // Current pos point size
  TColor           CurPointColor;     // Current pos point color
  bool             AutoMove;          // Auto move to last pos
  bool             LogTrack;          // Log recvd data to track
  int              Avg;               // Track average move to ignore
};

bool TrackConfigure( TForm *Owner, TrackOptions& op );
void Track2CfgOptions( TrackOptions& op );
void Cfg2TrackOptions( TrackOptions& op );

//Forms
bool SwitchTest( TForm *Owner, int doShow );
bool SwitchSpeed( TForm *Owner, int doShow  );
bool SwitchCompas( TForm *Owner, int doShow );
bool SwitchTrack( TForm *Owner, int doShow );

//[oz_Utils.cpp]
CONSTSTR  TimeStr( time_t Time );
CONSTSTR  TimeDiffStr( time_t TimeDiff );
TControl *FindControl( TWinControl *WinControl, CONSTSTR ComponentName );
CONSTSTR  FormatKm( double val );
void      ozi2UTM( double Lat, double Lon, int& E, int& N );
void      Val2DMS( double val, double& d, double& m, double& s );
void      Val2DM( double val, double& d, double& m );
bool      DMS2Val( double d, double m, double s, double& v );
bool      DM2Val( double d, double m, double& v );
void      ForceHint( TObject *Sender, int x = -1, int y = -1 );

//[oz_PlaceEdit.cpp]
bool     EditPlacePos( PHCoord p );

//Opts
extern PHStorageLink  Opt;
#define GOPT( nm, def )  Opt->Read( nm, def )
#define SOPT( nm, val )  Opt->Write( nm, val )

#define DEF_SWITCH( nm )  static T##nm##Form *Form = NULL;                  \
                          bool Switch##nm( TForm *Owner, int doShow )       \
                            {                                               \
                              if ( doShow == 1 || !Form && doShow == -1 ) {      \
                                if ( !Form ) Form = new T##nm##Form(Owner); \
                                Form->Show();                               \
                                Form->BringToFront();                       \
                                return true;                                \
                              } else                                        \
                              if ( doShow == 0 || Form && doShow == -1 ) {      \
                                if (Form) Form->Close();                    \
                                return false;                               \
                              }                                             \
                           return Form != NULL;                             \
                          }

#define LNG       TranslatePSTR
#define SLNG( v ) TranslateSTR( v ).c_str()
#define _LNG( v ) v
#endif
